package com.caifu.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caifu.mapper.SysMenuMapper;
import com.caifu.pojo.SysMenu;
import com.caifu.pojo.SysUser;
import com.caifu.pojo.SysUserToken;
import com.caifu.service.SysMenuService;
import com.caifu.service.SysUserService;
import com.caifu.service.SysUserTokenService;
import com.caifu.util.ShiroUtil;
import com.caifu.util.Util;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.*;

public class CustomRealm extends AuthorizingRealm{

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysMenuService menuService;
    @Resource
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SessionDAO sessionDAO;

    @Autowired
    private SysUserTokenService tokenService;

    /*@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
        String loginName = user.getLoginName();
        //根据用户名去数据库查询用户信息
        SysUser user = loginService.getUserByName(loginName);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            for (Permissions permissions : role.getPermissions()) {
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
            }
        }
        return simpleAuthorizationInfo;
    }*/

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        try {
            //获取登录用户名
            SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
            //添加角色和权限
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            Set<String> permissionSet = new HashSet<>();
            List<Map<String,Object>> list = menuService.getMenuByUser(user.getUserNo());
            for (Map<String,Object> menu : list) {
                //添加角色
                //simpleAuthorizationInfo.addRole(role.getRoleName());
                //添加权限
                permissionSet.add((String) menu.get("PERMISSION_CODE"));
            }

            //设置按钮权限

            List<SysMenu> menuList = sysMenuMapper.getMenuPermissionCodeByUserNo(user.getUserNo()+"");
            menuList.removeIf(Util::isNull);
            menuList.forEach(sysMenu ->
                    permissionSet.add(sysMenu.getPermissionCode()));

            //permissionSet.forEach(simpleAuthorizationInfo::addStringPermission);

//            permissionSet.forEach(System.out::println);
            simpleAuthorizationInfo.setStringPermissions(permissionSet);

            return simpleAuthorizationInfo;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证，然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户信息
        String loginName = authenticationToken.getPrincipal().toString();
        SysUser user = null;
        try{
            user = userService.getUserByLoginName(loginName);
        }catch (Exception e){
            e.printStackTrace();
        }
        if (user == null) {
            //这里返回后会报出对应异常
            throw new UnknownAccountException("账户不存在!");
        } else {

            //以下为只允许同一账户单个登录
//            Collection<Session> sessions = sessionDAO.getActiveSessions();
//            if(sessions.size()>0) {
//                for (Session session : sessions) {
//                    System.out.println("::::::::::::::::" + session);
//                    //获得session中已经登录用户的名字
//                    if(null!=session.getAttribute("user")) {
//                        String loginUsername = ((SysUser)session.getAttribute("user")).getLoginName();
//                        System.out.println("::::::::::::::::" + loginUsername);
//                        if (loginName.equals(loginUsername)) {  //这里的username也就是当前登录的username
//                            session.setTimeout(0);  //这里就把session清除，
//                            System.out.println("清除了");
//                            //退出登陆时, 移除token
//                            //tokenService.remove(new QueryWrapper<SysUserToken>().eq("USER_NO",user.getUserNo()));
//                        }
//                    }
//                }
//            }

            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
            return info;
        }
    }

    /**
     * 密码验证器
     * @param credentialsMatcher
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
        shaCredentialsMatcher.setHashAlgorithmName(ShiroUtil.hashAlgorithmName);
        shaCredentialsMatcher.setHashIterations(ShiroUtil.hashIterations);
        super.setCredentialsMatcher(shaCredentialsMatcher);
    }
}
